package com.guo.Test01;

import java.util.ArrayList;
import java.util.Collection;

public class TestArrayList {
    public static void main(String[] args) {
        //ArrayList底层是Object数组,初始化会将EMPTY_ELEMENTDATA变量的地址先放入其中
        ArrayList a1=new ArrayList();
        //如果初始化时参数为0容量会和默认定义的大小一样，如果初始化参数大于零就会按照初始化大小生成
        ArrayList a2=new ArrayList(0);

        //想用数组中的elementData数组比较，结果找不到，transient属性还可以起到私有化的过程吗？
        //下面返回false,推测可能是因为添加的时候赋了一个新的数组地址
        //System.out.println((new ArrayList())==(new ArrayList()));

        //在实现这个时有个问提:上面两个对象的底层都是通过底层常量数组初始化，为什么在添加后却不同了呢？
        /*寻找问题的步骤：
        1.找到了add方法，发现会用size+1执行一个名为ensureCapacityInternal的方法后才会将值赋给数组，推测可能在方法内进行赋值工作
        2.ensureCapacityInternalhou方法先是比较了两个数组的地址，如果一样就会将选出最大的值出来，如果数组容量小于传进来的值时会执行grow方法
        3.grow方法后续推导有些复杂，不过得到一些信息，当时数组中元素量（如果是刚初始化时值会在步骤2中被替换成10）与当时数组容量的大小的1.5倍大小比较，
        将最大的值保留下来，还有如果数组容量大小大于定义的MAX_ARRAY_SIZE的大小，就会执行一种定值操作，只会返回两个极大值。
        然后将通过Arrays的copyOf方法创建一个原来数据的新数组。
        得到结论:如果添加时元素个数小于容量大小就会在第二步停止，如果大于容器大小就会进行后面所谓的扩容操作,对象中的size++
        */
        a1.add("123");
        //就是返回对象中的size的值
        a1.size();
        //会执行方法rangeCheck,判断参数是否大于size，大于就会报错。然后执行从数组读取操作
        a1.get(0);
        //会将两个Collection集合的size大小相加，创建一个更大的数组，后将两个对象的数据放进去
        a1.addAll(a2);
        //就是将数组中所有属性的地址改成null，将size改为0
//        a1.clear();
        //未了解
//        a1.clone();
        //底层通过对象遍历数组查找，null值也可以查询
        a1.contains(0);
        //对象中的size是否为零
        a1.isEmpty();
        //删除就很有意思了，通过方法的重载可以通过下标或对象删除，通过将要删除元素的后面向前移动一步来完成
        a1.remove(0);
        //还是通过数组的遍历完成，但是将这个过程封装了起来
        a1.iterator();

        /*ArrayList结论:
        1.通过数组来实现底层存储
        2.初始化时其实使用的是定义好的常量方法，在使用添加时会创建一个容量为10的数组
        3.ArrayList方法使用size变量记录数组数据数量
        4.一般扩容是1.5倍大小扩容
        * */
    }
}
